#include "VSIndexBuffer.h"
#include "VSGraphicInclude.h"
#include "VSStream.h"
using namespace VSEngine2;
IMPLEMENT_RTTI(VSIndexBuffer,VSBind)
static bool gs_bStreamRegistered_VSVertexFormat = VSIndexBuffer::RegisterMainFactory();
bool VSIndexBuffer::ms_bRegisterMainFactory = false;
bool VSIndexBuffer::RegisterMainFactory()
{
	if (!ms_bRegisterMainFactory)
	{ 
		VSMain::AddInitialFuntion(VSIndexBuffer::InitialClassFactory); 
		ms_bRegisterMainFactory = true;
	} 
	return ms_bRegisterMainFactory;

}

bool VSIndexBuffer::InitialClassFactory()
{
	ms_ClassFactory.AddElement(ms_Type.GetName(),FactoryFunc);

	return 1;
}
VSObject * VSIndexBuffer::FactoryFunc()
{
	return VS_NEW VSIndexBuffer;

}
VSIndexBuffer::VSIndexBuffer()
{
	m_pDate = NULL;
	m_uiNum = 0;
	m_uiDT = VSDataBuffer::DT_USHORT;
	m_pLockDate = NULL;
}
VSIndexBuffer::~VSIndexBuffer()
{
	ReleaseResource();
	m_pDate = NULL;
	m_pLockDate = NULL;
}
unsigned int VSIndexBuffer::DiskUse()const
{
	unsigned int Used = VSBind::DiskUse();
	Used += sizeof(VSDataBuffer *);
	Used += sizeof(unsigned int) * 2;
	return Used;
}

bool VSIndexBuffer::Save(VSStream & rStream,unsigned int &iSaveUse)const
{
	if(!VSBind::Save(rStream,iSaveUse))
		return 0;

// 	VSDataBuffer * Temp = m_pDate;
// 
// 	if(!rStream.Write(&Temp,sizeof(VSDataBuffer *)))
// 		return 0;
	if(!rStream.WriteObjectPtr(m_pDate))
		return 0;
	iSaveUse += sizeof(VSDataBuffer *);

	if(!rStream.Write(&m_uiNum,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);

	if(!rStream.Write(&m_uiDT,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);
	return 1;
}
bool VSIndexBuffer::Load(VSStream & rStream,unsigned int &iSaveUse)
{
	if(!VSBind::Load(rStream,iSaveUse))
		return 0;
// 	VSDataBuffer * Temp = NULL;
// 	if(!rStream.Read(&Temp,sizeof(VSDataBuffer *)))
// 		return 0;
// 	AddLink(Temp);
	if(!rStream.ReadObjectPtr(m_pDate))
		return 0;
	iSaveUse += sizeof(VSDataBuffer *);

	if(!rStream.Read(&m_uiNum,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);

	if(!rStream.Read(&m_uiDT,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);
	return 1;
}

bool VSIndexBuffer::Clone(const VSObject *pObject,unsigned int uiType)
{
	const VSIndexBuffer* Temp = DynamicCast<VSIndexBuffer>(pObject); 
	if(!Temp)
		return 0;
	if(VSBind::Clone(pObject,uiType))
	{


		VSDataBuffer * pTemp1  = Temp->m_pDate;
		VSDataBuffer * pTemp2 =(VSDataBuffer *)VSObject::GetInstance((pTemp1)->GetType().GetName());
		pTemp2->Clone(pTemp1,uiType);
		m_pDate = pTemp2;
		m_uiNum = Temp->m_uiNum;
		m_uiDT = Temp->m_uiDT;
		return 1;	
	}
	else
		return 0;
}
bool VSIndexBuffer::LoadResource(VSRenderer * pRender)
{
	if(!VSBind::LoadResource(pRender))
	{
		return 0;
	}
	if (m_uiMemType == MT_VRAM)
	{
		m_pDate = NULL;
	}
	return 1;
}
bool VSIndexBuffer::OnLoadResource(VSResourceIdentifier *&pID)
{
	if(!m_pUser)
		return 0;
	if(!m_pUser->OnLoadIBuffer(this,pID))
		return 0;
	return 1;
}
bool VSIndexBuffer::OnReleaseResource(VSResourceIdentifier *pID)
{
	if(!m_pUser)
		return 0;

	if(!m_pUser->OnReleaseIBuffer(pID))
		return 0;
	return 1;
}
void *VSIndexBuffer::Lock()
{
	if (m_pLockDate || m_bIsStatic)
	{
		return NULL;
	}
	if (m_pUser)
	{
		m_pLockDate = m_pUser->Lock(this);
	}

	return m_pLockDate;
}
void VSIndexBuffer::UnLock()
{
	if (!m_pLockDate || m_bIsStatic)
	{
		return;
	}
	if (m_pUser)
	{
		m_pUser->UnLock(this);
	}
	m_pLockDate = NULL;
}
bool VSIndexBuffer::SetDate(VSDataBuffer * pDate)
{
	if ((pDate->GetDT() != VSDataBuffer::DT_USHORT && pDate->GetDT() != VSDataBuffer::DT_UINT)
		|| !pDate->GetNum() || !pDate->GetDate())
	{
		return 0;
	}
	m_pDate = pDate;
	m_uiNum = pDate->GetNum();
	m_uiDT = pDate->GetDT();
	return 1;
}
bool VSIndexBuffer::Register(VSStream & rStream)const
{
	if (rStream.IsObjectRegister(this))
	{
		return 1;
	}
	if(!VSBind::Register(rStream))
		return 0;

	if (!m_pDate)
	{
		return 0;
	}
	if(!m_pDate->Register(rStream))
		return 0;
		
	return 1;
}
bool VSIndexBuffer::Link(VSStream & rStream)
{
	if(!VSBind::Link(rStream))
		return 0;

	//m_pDate = (VSDataBuffer *)rStream.GetMapValue(GetNextLink());
	rStream.LinkObjectPtr(m_pDate);
	if (!m_pDate)
	{
		return 0;
	}
	return 1;
}
unsigned int VSIndexBuffer::GetNum()const
{
	return m_uiNum;
}
unsigned int VSIndexBuffer::GetByteSize()const
{
	return VSDataBuffer::ms_uiDateTypeByte[m_uiDT] * m_uiNum;
}
VSIndexBuffer::VSIndexBuffer(unsigned int uiNum,unsigned int uiDT)
{
	VSMAC_ASSERT(uiNum);
	VSMAC_ASSERT(uiDT == VSDataBuffer::DT_USHORT || uiDT == VSDataBuffer::DT_UINT)
	m_pDate = NULL;
	m_uiNum = uiNum;
	m_uiDT = uiDT;
	m_pLockDate = NULL;
}